﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Web.Mvc;
using GsifWeb4.Models;
using GsifWeb4.ViewModels;

namespace GsifWeb4.Controllers
{
    public class CalenderController : Controller
    {
        gsifdbEntities gsifDB = new gsifdbEntities();

        //
        // GET: /Calender/

        [Authorize]
        public ActionResult Index()
        {
            if (!Common.IsUserAllowedToBeWebred(gsifDB, User.Identity.Name))
                return View("NotAuthorized");

            CalenderViewModel calViewModel = new CalenderViewModel(gsifDB, User.Identity.Name);
            calViewModel.ActivitesOnDate = null;
            calViewModel.SelectedDate = DateTime.Now;

            return View(calViewModel);
        }

        // Returns all events on the actual month
        public ActionResult AjaxGetEventsOnMonth(int year, int month)
        {
            DateTime fromDate = new DateTime(year, month, 1);
            DateTime toDate = fromDate.AddMonths(1);

            List<CalenderHelper.CalenderEvent> calenderEvents = new List<CalenderHelper.CalenderEvent>();

            // ******* Add all match dates ********
            var matches = (from match in gsifDB.match_gsif
                           where match.Datum >= fromDate && match.Datum < toDate
                           select match).ToList();

            AddMatchesToCalenderEvents(matches, calenderEvents);

            // ******* Add all training dates ********
            var trainings = (from training in gsifDB.traning_gsif
                             where training.Datum >= fromDate && training.Datum < toDate
                             select training).ToList();

            AddTrainingsToCalenderEvents(calenderEvents, trainings);

            // ******* Add all other dates ********
            var others = (from other in gsifDB.ovrigt_gsif
                          where other.Datum >= fromDate && other.Datum < toDate
                          select other).ToList();

            AddOtherToCalenderEvents(calenderEvents, others);

            return Json(calenderEvents.ToArray());
        }

        public ActionResult AjaxGetEventsOnDate(int year, int month, int day)
        {
            DateTime clickedDate = new DateTime(year, month, day);
            List<CalenderHelper.CalenderEvent> calenderEvents = new List<CalenderHelper.CalenderEvent>();

            // ******* Add all match dates ********
            var matches = (from match in gsifDB.match_gsif
                           where match.Datum == clickedDate
                           select match).ToList();            

            AddMatchesToCalenderEvents(matches, calenderEvents);

            // ******* Add all training dates ********
            var trainings = (from training in gsifDB.traning_gsif
                             where training.Datum == clickedDate
                             select training).ToList();

            AddTrainingsToCalenderEvents(calenderEvents, trainings);

            // ******* Add all other dates ********
            var others = (from other in gsifDB.ovrigt_gsif
                          where other.Datum == clickedDate
                          select other).ToList();

            AddOtherToCalenderEvents(calenderEvents, others);

            return Json(calenderEvents);
        }

        private static void AddOtherToCalenderEvents(List<CalenderHelper.CalenderEvent> calenderEvents, List<ovrigt_gsif> others)
        {
            foreach (var other in others)
            {
                string otherText = string.Format("{0}, {1}, {2}<br>{3}",
                    other.Lag,
                    other.Tid,
                    other.Plats,
                    other.Text
                    );

                calenderEvents.Add(new CalenderHelper.CalenderEvent()
                {
                    Text = otherText,
                    Id = (int)other.OvId,
                    TypeOfEvent = (int)CalenderHelper.CalenderEvent.EventType.Other,
                    Date = other.Datum.Value
                });
            }
        }

        private static void AddTrainingsToCalenderEvents(List<CalenderHelper.CalenderEvent> calenderEvents, List<traning_gsif> trainings)
        {
            foreach (var training in trainings)
            {
                string trainingText = string.Format("{0} tränar<br>klockan {1}<br>på {2}",
                    training.Lag,
                    training.Tid,
                    training.Plats
                    );

                calenderEvents.Add(new CalenderHelper.CalenderEvent()
                {
                    Text = trainingText + " " + (int)CalenderHelper.CalenderEvent.EventType.Training,
                    Id = (int)training.TrId,
                    TypeOfEvent = (int)CalenderHelper.CalenderEvent.EventType.Training,
                    Date = training.Datum.Value
                });
            }
        }

        private static void AddMatchesToCalenderEvents(List<match_gsif> matches, List<CalenderHelper.CalenderEvent> calenderEvents)
        {
            foreach (var match in matches)
            {
                string matchText = string.Format("{0} spelar {1}match<br>klockan {2}<br>{3} mot <b>{4}</b> på {5}",
                    match.Lag,
                    match.Typ,
                    match.Tid,
                    (HomeOrAway.GetStatusFromDbValue(HomeOrAway.AllStatuses, match.Plan) == HomeOrAway.Home ? "hemma" : "borta"),
                    match.Motstandare,
                    match.Plats
                    );

                calenderEvents.Add(new CalenderHelper.CalenderEvent()
                {
                    Text = matchText + " " + (int)CalenderHelper.CalenderEvent.EventType.Match,
                    Id = (int)match.MaId,
                    TypeOfEvent = (int)CalenderHelper.CalenderEvent.EventType.Match,
                    Date = match.Datum.Value
                });
            }
        }

        public JsonResult GetDatesAndColor(int year, int month)
        {
            
            DateTime firstDate = new DateTime(year, month, 1);
            DateTime lastDate = firstDate.AddMonths(1).AddDays(-1);

            // Get matches
            var matches = (from match in gsifDB.match_gsif
                           where match.Datum >= firstDate && match.Datum <= lastDate
                           select match).ToList();

            // Get trainings
            var trainings = (from training in gsifDB.traning_gsif
                             where training.Datum >= firstDate && training.Datum <= lastDate
                             select training).ToList();

            // Get other activities
            var others = (from other in gsifDB.ovrigt_gsif
                          where other.Datum >= firstDate && other.Datum <= lastDate
                          select other).ToList();

            List<ClassNameOnDate> classNamesOnDates = new List<ClassNameOnDate>();
            for (int i = 0; i < DateTime.DaysInMonth(year, month); i++)
            {
                DateTime dateToCheck = firstDate.AddDays(i);

                string date = dateToCheck.Day.ToString();
                string className = "cal";

                var match = matches.Where(m => m.Datum.Value == dateToCheck).FirstOrDefault();
                if (match != null)
                    className += "_match";

                var training = trainings.Where(m => m.Datum.Value == dateToCheck).FirstOrDefault();
                if (training != null)
                    className += "_training";

                var other = others.Where(m => m.Datum.Value == dateToCheck).FirstOrDefault();
                if (other != null)
                    className += "_other";

                if (className != "cal")
                    classNamesOnDates.Add(new ClassNameOnDate() { Date = dateToCheck.Day.ToString(), ClassName = className });
            }

            return Json(classNamesOnDates, JsonRequestBehavior.AllowGet);
        }

        public class ClassNameOnDate
        {
            public string Date { get; set; }
            public string ClassName { get; set; }


        }

        //
        // GET: /Calender/Details/5

        public ActionResult Details(int id)
        {
            return View();
        }

        // GET
        public ActionResult CreateEvent(int calenderEventType)
        {
            if (!Common.IsUserAllowedToBeWebred(gsifDB, User.Identity.Name))
                return View("NotAuthorized");

            if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Match)
            {
                match_gsif newMatchEvent = GetNewMatch();
                MatchViewModel matchViewModel = new MatchViewModel(newMatchEvent);

                ViewBag.Title = "Lägg till match";
                return View("MatchEvent", matchViewModel);
            }
            else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Training)
            {
                traning_gsif newTrainingEvent = GetNewTraining();
                TrainingViewModel trainingViewModel = new TrainingViewModel(newTrainingEvent);

                ViewBag.Title = "Lägg till träning";
                return View("TrainingEvent", trainingViewModel);
            }
            else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Other)
            {
                ovrigt_gsif newOtherEvent = GetNewOtherEvent();
                OtherEventViewModel otherEventViewModel = new OtherEventViewModel(newOtherEvent);
                ViewBag.Title = "Lägg till övrig aktivitet";

                return View("OtherEvent", otherEventViewModel);
            }
            else
                return View("InvalidCalenderEvent");

        }

        private match_gsif GetNewMatch()
        {
            match_gsif newMatchEvent = new match_gsif();
            newMatchEvent.MaId = 0; // will be set in Post action
            newMatchEvent.Lag = Team.MenA.DbValue;
            newMatchEvent.Typ = MatchType.League.DbValue;
            newMatchEvent.Plan = HomeOrAway.Home.DbValue;
            newMatchEvent.User = "";
            newMatchEvent.Plats = "";
            newMatchEvent.Tid = "";
            newMatchEvent.Motstandare = "";

            return newMatchEvent;

        }

        private traning_gsif GetNewTraining()
        {
            traning_gsif newTrainingEvent = new traning_gsif();
            newTrainingEvent.TrId = 0; // will be set in Post action
            newTrainingEvent.Lag = Team.MenA.DbValue;
            newTrainingEvent.User = "";
            newTrainingEvent.Plats = "";
            newTrainingEvent.Tid = "";

            return newTrainingEvent;
        }

        private ovrigt_gsif GetNewOtherEvent()
        {
            ovrigt_gsif newOtherEvent = new ovrigt_gsif();
            var nextID = gsifDB.ovrigt_gsif.Max(p => p.OvId) + 1;
            newOtherEvent.OvId = nextID;
            newOtherEvent.Lag = Team.All.DbValue;
            newOtherEvent.User = "";
            newOtherEvent.Plats = "";
            newOtherEvent.Tid = "";

            return newOtherEvent;
        }


        [HttpPost]
        public ActionResult CreateEvent(int calenderEventType, FormCollection collection)
        {
            try
            {
                if (!Common.IsUserAllowedToBeWebred(gsifDB, User.Identity.Name))
                    return View("NotAuthorized");

                DateTime selectedDate;
                if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Match)
                {
                    match_gsif newMatch = new match_gsif();
                    newMatch.MaId = Sequence.GetNextFromSequence(gsifDB, Sequence.MatchOchTraningsId);
                    UpdateMatchEvent(newMatch);
                    gsifDB.match_gsif.AddObject(newMatch);
                    selectedDate = newMatch.Datum.Value;
                }
                else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Training)
                {
                    traning_gsif newTrainingEvent = GetNewTraining();
                    UpdateTrainingEvent(newTrainingEvent);
                    newTrainingEvent.TrId = Sequence.GetNextFromSequence(gsifDB, Sequence.MatchOchTraningsId);
                    gsifDB.traning_gsif.AddObject(newTrainingEvent);
                    selectedDate = newTrainingEvent.Datum.Value;
                }
                else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Other)
                {
                    ovrigt_gsif newOtherEvent = GetNewOtherEvent();
                    UpdateOtherEvent(newOtherEvent);
                    gsifDB.ovrigt_gsif.AddObject(newOtherEvent);
                    selectedDate = newOtherEvent.Datum.Value;
                }
                else
                    return View("InvalidCalenderEvent");
                

                gsifDB.SaveChanges();

                CalenderViewModel calViewModel = new CalenderViewModel(gsifDB, User.Identity.Name);
                calViewModel.ActivitesOnDate = null;
                calViewModel.SelectedDate = selectedDate;

                return View("Index", calViewModel);
            }
            catch (Exception err)
            {
                return View();
            }
        }

        //
        // GET: /Calender/Edit/5/Ma
        public ActionResult Edit(int id, int calenderEventType)
        {
            if (!Common.IsUserAllowedToBeWebred(gsifDB, User.Identity.Name))
                return View("NotAuthorized");

            if (calenderEventType == -1)
            {
                return View();
            }

            if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Match)
            {
                var matchEvent = Common.GetMatchFromId(gsifDB, id);
                MatchViewModel matchViewModel = new MatchViewModel(matchEvent);

                ViewBag.Title = "Ändra match";
                return View("MatchEvent", matchViewModel);
            }
            else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Training)
            {
                traning_gsif trainingEvent = Common.GetTrainingFromId(gsifDB, id);
                TrainingViewModel trainingViewModel = new TrainingViewModel(trainingEvent);
                ViewBag.Title = "Ändra träning";
                return View("TrainingEvent", trainingViewModel);
            }
            else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Other)
            {
                ovrigt_gsif otherEvent = Common.GetOtherFromId(gsifDB, id);
                OtherEventViewModel otherEventViewModel = new OtherEventViewModel(otherEvent);

                ViewBag.Title = "Ändra övrit aktivitet";
                return View("OtherEvent", otherEventViewModel);
            }
            else
                return View("InvalidCalenderEvent");
        }

        //
        // POST: /Calender/Edit/5/Ma
        [HttpPost]
        public ActionResult Edit(int id, int calenderEventType, FormCollection collection)
        {
            try
            {
                if (!Common.IsUserAllowedToBeWebred(gsifDB, User.Identity.Name))
                    return View("NotAuthorized");

                DateTime selectedDate;

                if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Match)
                {
                    var matchEvent = Common.GetMatchFromId(gsifDB, id); 
                    if (matchEvent == null)
                        return View("InvalidCalenderEvent");
                                        
                    UpdateMatchEvent(matchEvent);
                    selectedDate = matchEvent.Datum.Value;
                }
                else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Training)
                {
                    var trainingEvent = Common.GetTrainingFromId(gsifDB, id);
                    if (trainingEvent == null)
                        return View("InvalidCalenderEvent");

                    UpdateTrainingEvent(trainingEvent);
                    selectedDate = trainingEvent.Datum.Value;
                }
                else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Other)
                {
                    var otherEvent = Common.GetOtherFromId(gsifDB, id);
                    if (otherEvent == null)
                        return View("InvalidCalenderEvent");

                    UpdateOtherEvent(otherEvent);
                    selectedDate = otherEvent.Datum.Value;
                }
                else
                {
                    return View("InvalidCalenderEvent");
                }


                gsifDB.SaveChanges();

                CalenderViewModel calViewModel = new CalenderViewModel(gsifDB, User.Identity.Name);
                calViewModel.ActivitesOnDate = null;
                calViewModel.SelectedDate = selectedDate;
                return View("Index", calViewModel);
            }
            catch
            {
                return View();
            }
        }

        private void UpdateMatchEvent(match_gsif matchEvent)
        {
            UpdateModel<match_gsif>(matchEvent, "Match");

            // Hemma/Borta
            StatusValue homeOrAway = HomeOrAway.GetStatusFromText(HomeOrAway.AllStatuses, Request["PlanDD"]);
            if (homeOrAway != null)
                matchEvent.Plan = homeOrAway.DbValue;

            // Lag
            StatusValue team = Team.GetStatusFromText(Team.AllTeams, Request["TeamDD"]);
            if (team != null)
                matchEvent.Lag = team.DbValue;

            // Typ av match (seriematch, träningsmatch mm)
            StatusValue typeOfGame = MatchType.GetStatusFromText(MatchType.AllStatuses, Request["MatchTypeDD"]);
            if (typeOfGame != null)
                matchEvent.Typ = typeOfGame.DbValue;
        }

        private void UpdateTrainingEvent(traning_gsif trainingEvent)
        {
            UpdateModel<traning_gsif>(trainingEvent, "Training");

            // Lag
            StatusValue team = Team.GetStatusFromText(Team.AllTeams, Request["TeamDD"]);
            if (team != null)
                trainingEvent.Lag = team.DbValue;
        }

        private void UpdateOtherEvent(ovrigt_gsif otherEvent)
        {
            UpdateModel<ovrigt_gsif>(otherEvent, "Other");

            // Lag
            StatusValue team = Team.GetStatusFromText(Team.AllTeams, Request["TeamDD"]);
            if (team != null)
                otherEvent.Lag = team.DbValue;
        }

        //
        // GET: /Calender/Delete/5/Ma
        public ActionResult Delete(int id, int calenderEventType)
        {
            if (!Common.IsUserAllowedToBeWebred(gsifDB, User.Identity.Name))
                return View("NotAuthorized");

            if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Match)
            {
                var matchEvent = Common.GetMatchFromId(gsifDB, id);
                if (matchEvent.StatExcist == "Y")
                    return View("MatchCouldNotBeDeleted");

                return View("DeleteMatch", matchEvent);
            }
            else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Training)
            {
                traning_gsif trainingEvent = Common.GetTrainingFromId(gsifDB, id);
                return View("DeleteTraining", trainingEvent);
            }
            else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Other)
            {
                ovrigt_gsif otherEvent = Common.GetOtherFromId(gsifDB, id);
                return View("DeleteOtherEvent", otherEvent);
            }
            else
                return View("InvalidCalenderEvent");
        }

        //
        // POST: /Calender/Delete/5

        [HttpPost]
        public ActionResult Delete(int id, int calenderEventType, FormCollection collection)
        {
            try
            {
                if (!Common.IsUserAllowedToBeWebred(gsifDB, User.Identity.Name))
                    return View("NotAuthorized");

                if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Match)
                {
                    var matchEvent = Common.GetMatchFromId(gsifDB, id);
                    if (matchEvent.StatExcist == "Y")
                        return View("MatchCouldNotBeDeleted");

                    gsifDB.match_gsif.DeleteObject(matchEvent);
                }
                else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Training)
                {
                    traning_gsif trainingEvent = Common.GetTrainingFromId(gsifDB, id);
                    gsifDB.traning_gsif.DeleteObject(trainingEvent);
                }
                else if (calenderEventType == (int)CalenderHelper.CalenderEvent.EventType.Other)
                {
                    ovrigt_gsif otherEvent = Common.GetOtherFromId(gsifDB, id);
                    gsifDB.ovrigt_gsif.DeleteObject(otherEvent);
                }
                else
                    return View("InvalidCalenderEvent");

                gsifDB.SaveChanges();
                return View("Deleted");
            }
            catch (Exception err)
            {
                HandleErrorInfo hei = new HandleErrorInfo(err, "Calender", "Delete");
                return View("Error", err);
            }
        }
    }
}
